package com.gxa.service.impl;


import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.gxa.common.R;
import com.gxa.entity.DistrictSysRole;
import com.gxa.entity.DistrictSysUser;
import com.gxa.mapper.DistrictUserMapper;
import com.gxa.mapper.RoleMapper;
import com.gxa.service.DistrictUserService;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class DistrictUserServiceImpl implements DistrictUserService {

    @Autowired
    private DistrictUserMapper districtUserMapper;

    @Autowired
    private RoleMapper roleMapper;

    //加密算法
    private final static String hashAlgorithmName = "md5";

    //散列次数
    private final static Integer hashIterations = 3;

    /**
     * 分页查询对应区级的所有信息
     * @param currentPage
     * @param pageSize
     * @param area
     * @return
     */
    @Override
    public R queryAllDistrictUsersByPage(int currentPage, int pageSize, String area) {
        R r = new R();
        try{
            Page<DistrictSysUser> page = PageHelper.startPage(currentPage,pageSize);
            List<DistrictSysUser> districtSysUsers = districtUserMapper.selectAllDistrictUsers(area);
            int count = (int) page.getTotal();
            r.setCode(200);
            r.setMsg("查询成功");
            r.setCount(count);
            r.setData(districtSysUsers);
        }catch (Exception e){
            r.setCode(500);
            r.setMsg("系统异常,查询失败,请联系管理员");
        }
        return r;
    }

    /**
     * 根据条件查询账号信息分页显示
     * @param userName
     * @param phone
     * @param organization
     * @param nickname
     * @param role
     * @param status
     * @return
     */
    @Override
    public R queryConditionalDistrictUser(String userName, String phone, String organization, String nickname, String role, String status,int currentPage,int pageSize,String area) {
        R r = new R();
        try{
            Map<String,Object> conditionalMap = new HashMap<>();
            conditionalMap.put("userName",userName);
            conditionalMap.put("phone",phone);
            conditionalMap.put("organization",organization);
            conditionalMap.put("nickname",nickname);
            conditionalMap.put("role",role);
            conditionalMap.put("status",status);
            conditionalMap.put("area",area);

            Page<DistrictSysUser> page = PageHelper.startPage(currentPage,pageSize);
            List<DistrictSysUser> districtSysUserList = districtUserMapper.selectConditionalDistrictUser(conditionalMap);
            int count = (int) page.getTotal();
            r.setCode(200);
            r.setMsg("查询成功！");
            r.setCount(count);
            r.setData(districtSysUserList);
        }catch (Exception e){
            r.setCode(500);
            r.setMsg("系统异常,查询失败,请联系管理员");
        }
        return r;
    }

    /**
     * 添加账户信息
     * @param districtSysUser
     * @return
     */
    @Override
    @Transactional
    public R addDistrictUser(DistrictSysUser districtSysUser) {
        R r = new R();
        try{
            //获取加密后的密码
            SimpleHash simpleHash = new SimpleHash(hashAlgorithmName,districtSysUser.getPassword(),districtSysUser.getNickname(),hashIterations);
            String newPwd = simpleHash.toString();
            districtSysUser.setPassword(newPwd);
            districtSysUser.setStatus("启用中");
            districtSysUser.setSalt(districtSysUser.getNickname());
            districtSysUser.setWechat("未绑定");

            //判断要添加的账号是否已经存在
            DistrictSysUser selectedDistrictSysUser = districtUserMapper.selectDistrictUserByNickname(districtSysUser.getNickname());
            if(selectedDistrictSysUser == null){
                //账号不存在，进行添加
                districtUserMapper.insertDistrictUser(districtSysUser);
                //查询该账户对应角色的关联账号数
                DistrictSysRole districtSysRole = roleMapper.selectRoleByName(districtSysUser.getRole());
                //修改角色关联的账号数 原关联账号数+1
                Map<String,Object> map = new HashMap<>();
                map.put("roleName",districtSysUser.getRole());
                map.put("userNumber",districtSysRole.getUserNumber() + 1);
                roleMapper.updateUserNumberByRoleName(map);
                r.setCode(200);
                r.setMsg("添加成功！");
            }else {
                r.setCode(200);
                r.setMsg("添加失败，要添加是账号已存在！");
            }
        }catch (Exception e){
            //手动回滚
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            r.setCode(500);
            r.setMsg("系统异常,添加失败,请联系管理员");
        }
        return r;
    }

    /**
     * 根据账号编号删除账号信息
     * @param id
     * @return
     */
    @Override
    @Transactional
    public R deleteDistrictUserById(int id) {
        R r = new R();
        try{
            //先根据账号ID查询账号信息
            DistrictSysUser districtSysUser = districtUserMapper.selectDistrictUserById(id);
            //删除账号信息
            int row = districtUserMapper.deleteDistrictUserById(id);
            if(row > 0){
                //查询该账户对应角色的关联账号数
                DistrictSysRole districtSysRole = roleMapper.selectRoleByName(districtSysUser.getRole());
                //修改角色关联的账号数 原关联账号数-1
                Map<String,Object> map = new HashMap<>();
                map.put("roleName",districtSysUser.getRole());
                map.put("userNumber",districtSysRole.getUserNumber() - 1);
                roleMapper.updateUserNumberByRoleName(map);
                r.setCode(200);
                r.setMsg("删除成功！");
            }else {
                r.setCode(1001);
                r.setMsg("删除失败！");
            }
        }catch (Exception e){
            //手动回滚
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            r.setCode(500);
            r.setMsg("系统异常,删除失败,请联系管理员");
        }
        return r;
    }

    /**
     * 启用账号
     * @param id
     * @return
     */
    @Override
    public R enableDistrictUser(int id) {
        R r = new R();
        try{
            districtUserMapper.enableDistrictUserStatus(id);
            r.setCode(200);
            r.setMsg("启用成功！");
        }catch (Exception e){
            e.printStackTrace();
            r.setCode(500);
            r.setMsg("系统异常,启用失败,请联系管理员");
        }
        return r;
    }

    /**
     * 禁用账号
     * @param id
     * @return
     */
    @Override
    public R disableDistrictUser(int id) {
        R r = new R();
        try{
            districtUserMapper.disableDistrictUserStatus(id);
            r.setCode(200);
            r.setMsg("禁用成功！");
        }catch (Exception e){
            e.printStackTrace();
            r.setCode(500);
            r.setMsg("系统异常,禁用失败,请联系管理员");
        }
        return r;
    }

    /**
     * 重置密码
     * @param id
     * @return
     */
    @Override
    @Transactional
    public R resetPassword(int id) {
        R r = new R();
        try {
            //先根据账号ID查询账号信息
            DistrictSysUser districtSysUser = districtUserMapper.selectDistrictUserById(id);
            //重置密码为123456，获取重置密码后的加密密码
            SimpleHash simpleHash = new SimpleHash(hashAlgorithmName,"123456",districtSysUser.getNickname(),hashIterations);
            String newPwd = simpleHash.toString();
            Map<String,Object> map = new HashMap<>();
            map.put("id",id);
            map.put("newPwd",newPwd);
            districtUserMapper.resetPassword(map);
            r.setCode(200);
            r.setMsg("重置密码成功！");
        }catch (Exception e){
            //手动回滚
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            r.setCode(500);
            r.setMsg("系统异常,重置密码失败,请联系管理员");
        }
        return r;
    }

    /**
     * 根据账号ID查询账号信息
     * @param id
     * @return
     */
    @Override
    public R queryDistrictUserById(int id) {
        R r = new R();
        try{
            DistrictSysUser districtSysUser = districtUserMapper.selectDistrictUserById(id);
            if(districtSysUser != null){
                r.setCode(200);
                r.setMsg("查询成功！");
                r.setData(districtSysUser);
            }else {
                r.setCode(1002);
                r.setMsg("查询的账号不存在！");
            }
        }catch (Exception e){
            e.printStackTrace();
            r.setCode(500);
            r.setMsg("系统异常,查询失败,请联系管理员");
        }
        return r;
    }

    /**
     * 修改账号信息
     * @param districtSysUser
     * @return
     */
    @Override
    @Transactional
    public R updateDistrictUser(DistrictSysUser districtSysUser) {
        R r = new R();
        try {
            //根据账号ID获取账号的状态和是否绑定微信
            DistrictSysUser selectedDistrictSysUser = districtUserMapper.selectDistrictUserById(districtSysUser.getUserId());
            String oldWechat = selectedDistrictSysUser.getWechat();
            String oldStatus = selectedDistrictSysUser.getStatus();
            String oldArea = selectedDistrictSysUser.getArea();
            districtSysUser.setWechat(oldWechat);
            districtSysUser.setStatus(oldStatus);
            districtSysUser.setArea(oldArea);
            //获取该账号所属角色是否发生变化
            String oldRole = selectedDistrictSysUser.getRole();
            //根据账号ID删除账号信息
            districtUserMapper.deleteDistrictUserById(districtSysUser.getUserId());
            //获取加密后的密码
            SimpleHash simpleHash = new SimpleHash(hashAlgorithmName,districtSysUser.getPassword(),districtSysUser.getNickname(),hashIterations);
            String newPwd = simpleHash.toString();
            districtSysUser.setPassword(newPwd);
            districtSysUser.setSalt(districtSysUser.getNickname());
            districtUserMapper.insertDistrictUserWithFixedId(districtSysUser);
            if(oldRole != districtSysUser.getRole()){
                //该账号原角色不等于修改后的角色，原角色关联账号数-1，新角色关联账号数+1
                //原角色关联账号数-1
                //查询该账户对应角色的关联账号数
                DistrictSysRole oldDistrictSysRole = roleMapper.selectRoleByName(oldRole);
                //修改角色关联的账号数 原关联账号数-1
                Map<String,Object> reduceMap = new HashMap<>();
                reduceMap.put("roleName",oldRole);
                reduceMap.put("userNumber",oldDistrictSysRole.getUserNumber() - 1);
                roleMapper.updateUserNumberByRoleName(reduceMap);
                //新角色关联账号数+1
                //查询该账户对应角色的关联账号数
                DistrictSysRole newDistrictSysRole = roleMapper.selectRoleByName(districtSysUser.getRole());
                //修改角色关联的账号数 原关联账号数+1
                Map<String,Object> addMap = new HashMap<>();
                addMap.put("roleName",districtSysUser.getRole());
                addMap.put("userNumber",newDistrictSysRole.getUserNumber() + 1);
                roleMapper.updateUserNumberByRoleName(addMap);
            }
            r.setCode(200);
            r.setMsg("修改成功！");
        }catch (Exception e){
            //手动回滚
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            r.setCode(500);
            r.setMsg("系统异常,修改失败,请联系管理员");
        }
        return r;
    }

    /**
     * 修改密码
     * @param id
     * @param newPassword
     * @return
     */
    @Override
    @Transactional
    public R changePassword(int id, String newPassword) {
        R r = new R();
        try{
            //根据账号ID查询账号信息
            DistrictSysUser selectedDistrictSysUser = districtUserMapper.selectDistrictUserById(id);
            SimpleHash simpleHash = new SimpleHash(hashAlgorithmName,newPassword,selectedDistrictSysUser.getSalt(),hashIterations);
            String newPwd = simpleHash.toString();
            Map<String,Object> map = new HashMap<>();
            map.put("id",id);
            map.put("newPwd",newPwd);
            districtUserMapper.resetPassword(map);
            r.setCode(200);
            r.setMsg("修改密码成功！");
        }catch (Exception e){
            //手动回滚
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            r.setCode(500);
            r.setMsg("系统异常,修改密码失败,请联系管理员");
        }
        return r;
    }

    /**
     * 根据账号名称查询账号信息
     * @param userName
     * @return
     */
    @Override
    public R queryDistrictUserByUserName(String userName) {
        R r = new R();
        try {
            DistrictSysUser districtSysUser = districtUserMapper.selectDistrictUserByUserName(userName);
            if(districtSysUser != null){
                r.setCode(200);
                r.setMsg("查询成功！");
                r.setData(districtSysUser);
            }else {
                r.setCode(1002);
                r.setMsg("查询的账号不存在！");
            }
        }catch (Exception e){
            e.printStackTrace();
            r.setCode(500);
            r.setMsg("系统异常,查询失败,请联系管理员");
        }
        return r;
    }
}
